#pragma once
#include <iostream>
#include <vector>
#include <cmath>
#include<limits>
#include<fstream>
#include<string>
#include <algorithm>
#include <memory>
#include <cwchar>
#include <locale>
#include <codecvt>
#include<windows.h>
//#include<sstream>
#include"Function.h"

using namespace std;

// 飞行线结构体
struct FlightLine {
    int id;
    double x1, y1, x2, y2;

    // 计算线段包围盒
    pair<pair<double, double>, pair<double, double>> getBoundingBox() const {
        return {
            {min(x1, x2), min(y1, y2)}, // minX, minY
            {max(x1, x2), max(y1, y2)}  // maxX, maxY
        };
    }
};
// 定义查询点的结构体
struct QueryPoint {
    double x, y;
};


// KD树的节点
struct KDNode {
    int id;
    FlightLine line;
    shared_ptr<KDNode> left;
    shared_ptr<KDNode> right;
    int axis; // 分割轴 (0表示x轴，1表示y轴)
    double splitValue; // 分割值

    KDNode(const FlightLine& line, int axis, double split)
        : id(line.id), line(line), left(nullptr), right(nullptr),
        axis(axis), splitValue(split) {}
};

class UserInputDataProcessor {
private:
    int flightNum, queryPointNum;//飞行线数量与查询点数量
    vector < vector < wstring >> FlightData, QueryPointData;// , QueryPointData_Point;
    vector<int> results;// = findNearestFlightLine(flightLines, queryPoints);
    int currentLine;

    // CSV行分割辅助函数
    vector<wstring> splitCSVLine(const wstring& line);

    int readCSVFile(wifstream& file);

    int readTextFile(wifstream& file);

    void processFlightLine(int id, double x1, double y1, double x2, double y2);

    void processQueryPoint(int id, double x, double y);

    // 构建KD树
    shared_ptr<KDNode> buildKDTree(vector<FlightLine>& flightLines, int depth = 0);

    // 计算两点距离的平方（避免开方提高效率）
    double distanceSquared(double x1, double y1, double x2, double y2);

    ////暴力方法求解最近飞行线
    //void findNearestFlightLine(const vector<FlightLine>& flightLines, const vector<QueryPoint>& queryPoints);

    // 计算点到线段的最短距离（与之前相同）
    double pointToLineDistance(double px, double py, const FlightLine& line);

    void searchKDTree(shared_ptr<KDNode> node, const QueryPoint& query,
        double& minDist, int& nearestId);

    // KD树最近邻搜索
    //void nearestNeighborSearch(shared_ptr<KDNode> node, const QueryPoint& query, int depth, double& minDist, int& nearestId);

    // 使用KD树优化查找最近飞行线
    void findNearestFlightLineKDTree(const vector<FlightLine>& flightLines, const vector<QueryPoint>& queryPoints);

public:
    vector<FlightLine> FlightLines;
    vector<QueryPoint> QueryPoints;
    vector<FlightLine> DirectlyInputFlightLines;
    vector<QueryPoint> DirectlyInputQueryPoints;
    //int cs;

    UserInputDataProcessor();

    int getFlightNum();

    int getQueryPointNum();

    int getCurrentLine();

    void getFlightDataReference(vector<vector<wstring>>& newdata);

    void getQueryPointDataReference(vector<vector<wstring>>& newdata);

    void getQueryPointData_PointReference(vector<vector<wstring>>& newdata);

    //传入查询的的坐标(Px,Py)，已知飞行线的两个端点(Ax,Ay)和(Bx,By)，返回查询点到飞行线的垂足坐标
    // 返回值: 最近点坐标(x,y)
    std::pair<double, double> findClosestPointOnSegment(double Px, double Py,double Ax, double Ay,
        double Bx, double By) const;

    int readDataFile(wstring filePath);

    void finishDirectInput();
    //std::shared_ptr<KDNode> InsertFlightLine(std::shared_ptr<KDNode> node, const FlightLine& line, int depth = 0);
        // 共用的数据结构初始化
    void initDataStructures(
        int flight_num = -1,
        int query_point_num = -1,
        bool resizeFlightLines = true
    );


};
